﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public interface IMutexWindow
{
    void Show();
    void Hide();
    bool IsVisible { get; }

    void TweenPlay(bool forward);

    UIRoot ViewPortRoot { get; }
}

public class SingleWindow<T> : SingletonMono<T>, IMutexWindow where T : UnityEngine.Component
{
    public List<IMutexWindow> pairList = new List<IMutexWindow>();

    //public UIPanel panel;
    public GameObject windowGO;

    public UIRoot viewPortRoot;
    public UIRoot ViewPortRoot { get { return viewPortRoot; } }

    public List<UIRoot> otherRootList;

    public TweenPosition tweenPosition;

    public UIButton close;

    public virtual bool MutexWindow { get { return false; } }

    public virtual void Request() {}

    public virtual List<GameObject> PairWindowList { get { return null; } }

    public bool IsVisible { get { return windowGO.activeSelf; } }

    public void TweenPlay(bool forward)
    {
        if (tweenPosition != null)
        {
            tweenPosition.Play(forward);
        }
    }

    public override void Awake()
    {
        base.Awake();

        windowGO = gameObject.transform.FindChild("Window").gameObject;

        SingleWindowManager.windowList.Add(this);

        close = Util.Find<UIButton>(gameObject, "CloseButton");
        if (close == null && viewPortRoot)
        {
            close = Util.Find<UIButton>(viewPortRoot, "CloseButton");
        }

        if (close != null)
        {
            UIEventListener.Get(close).onClick += OnCloseButtonClick;

            SingleWindowManager.mutexWindowList.Add(this);
        }

        tweenPosition = windowGO.GetComponent<TweenPosition>();

        foreach (List<IMutexWindow> list in SingleWindowManager.pairWindowList)
        {
            if (list.Contains(this))
            {
                foreach (IMutexWindow win in list)
                {
                    if (win != this)
                    {
                        //Debug.LogWarning(this.windowGO.transform.parent.name + " " + win);
                        pairList.Add(win);
                    }
                }
            }
        }


        //Debug.Log(this + ": " + pairList.Count);
        //panel = UITools.FindControl<UIPanel>(gameObject, "Panel");
    }

    public void Toggle()
    {
        if (windowGO == null)
            return;

        //panel.gameObject.SetActive(!panel.gameObject.activeSelf);
        if (windowGO.activeSelf == false)
        {
            Show();
        }
        else
        {
            Hide();
        }
    }

    public void Show()
    {
        show();
    }

    private void show()
    {
        if (SingleWindowManager.mutexWindowList.Contains(this))
        {
            foreach (IMutexWindow win in SingleWindowManager.mutexWindowList)
            {
                if (win == this)
                    continue;

                //Debug.Log(win);
                //Debug.Log(pairList.Count);
                if (!pairList.Contains(win))
                {
                    win.Hide();
                }
            }

            foreach (IMutexWindow win in pairList)
            {
                if (win.IsVisible)
                {
                    //Debug.Log(win);
                    TweenPlay(true);

                    win.TweenPlay(true);
                }
            }

            //Debug.Log("SingleWindowManager");
            if (!SingleWindowManager.mutexShowingWindow.Contains(this))
            {
                //Debug.Log("SingleWindowManager.Add");
                SingleWindowManager.mutexShowingWindow.Add(this);
            }
        }
        
        windowGO.SetActive(true);

        // window collider 
        if (close != null)
        {
            BoxCollider col = windowGO.GetComponent<BoxCollider>();
            if (col == null)
            {
                col = NGUITools.AddWidgetCollider(windowGO);
                col.center = new Vector3(col.center.x, col.center.y, 0.001f);
            }
        }

        // to be fixed : for UIButton ColorUpdate Bug....  
        UIButton[] butList = GetComponentsInChildren<UIButton>(true);
        foreach (UIButton but in butList)
        {
            if (but.isEnabled == false)
            {
                but.isEnabled = true;
                but.isEnabled = false;
            }
        }

        if (viewPortRoot != null)
        {
            viewPortRoot.gameObject.SetActive(true);
        }

        foreach (UIRoot r in otherRootList)
        {
            r.gameObject.SetActive(true);
        }

        OnShow();
    }

    public void Hide()
    {
        if (IsVisible == false)
            return;
        
        windowGO.SetActive(false);

        //Debug.Log("SingleWindowManager");
        if (SingleWindowManager.mutexShowingWindow.Contains(this))
        {
            //Debug.Log("SingleWindowManager.Remove");
            SingleWindowManager.mutexShowingWindow.Remove(this);
        }

        if (viewPortRoot != null)
        {
            viewPortRoot.gameObject.SetActive(false);
        }

        foreach (UIRoot r in otherRootList)
        {
            r.gameObject.SetActive(false);
        }

        foreach (IMutexWindow win in pairList)
        {
            if (win.IsVisible)
            {
                TweenPlay(false);

                win.TweenPlay(false);
            }
        }

        OnHide();
    }

    public virtual void OnShow()
    {
       
    }

    public delegate void OnWindowHide();
    public OnWindowHide onWindowHide;
    public virtual void OnHide()
    {
        if (onWindowHide != null)
        {
            onWindowHide();
        }

        ClearEvent();
    }

    private void ClearEvent()
    {
        if (onWindowHide != null)
        {
            System.Delegate[] invList = onWindowHide.GetInvocationList();
            foreach (OnWindowHide handler in invList)
            {
                onWindowHide -= handler;
            }
        }
    }

    protected virtual void OnCloseButtonClick(GameObject go)
    {
        Hide();
    }

    public void SetActive(bool active)
    {
        windowGO.SetActive(active);

        if (viewPortRoot != null)
        {
            viewPortRoot.gameObject.SetActive(active);
        }

        foreach (UIRoot r in otherRootList)
        {
            r.gameObject.SetActive(active);
        }
    }
}
